<?php

namespace api\modules\v1\forms\base;

use common\models\base\Project;
use common\models\member\Member;
use services\member\MemberProjectService;
use services\member\MemberService;
use Yii;
use yii\base\Model;


class ProjectForm extends Model
{
    /**
     * @var int $id ID
     * @var int $project_name 项目名称
     * @var string $sort 排序
     * @var int $status 状态
     * @var array $member_ids 项目管理员IDs
     */
    public $id;
    public $project_name;
    public $sort;
    public $status;
    public $member_ids;

    /**
     * @var Project $_project
     * @var int[] $_memberIdsFormat
     * @var Member[] $_memberList
     * @var Member[] $_projectMemberList
     */
    protected $_project;
    protected $_memberIdsFormat;
    protected $_memberList;
    protected $_projectMemberList;


    public function rules()
    {
        return [
            // 参数验证
            [['project_name', 'sort', 'status'], 'required', 'message' => '{attribute}不能为空', 'on' => ['create']],
            [['id', 'project_name', 'sort', 'status'], 'required', 'message' => '{attribute}不能为空', 'on' => ['edit']],
            [['id'], 'required', 'message' => '{attribute}不能为空', 'on' => ['delete']],
            [['id'], 'required', 'message' => '{attribute}不能为空', 'on' => ['edit_admin']],

            [['id'], 'checkId', 'skipOnEmpty' => false, 'on' => ['edit', 'delete', 'edit_admin']],
            [['project_name'], 'checkProjectName', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
            [['sort'], 'checkSort', 'skipOnEmpty' => true, 'on' => ['create', 'edit']],
            [['status'], 'checkStatus', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
            [['member_ids'], 'checkMemberIds', 'skipOnEmpty' => false, 'on' => ['edit_admin']],
        ];
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();

        // 新增
        $scenarios['create'] = ['project_name', 'sort', 'status'];

        // 编辑
        $scenarios['edit'] = ['id', 'project_name', 'sort', 'status'];

        // 编辑项目管理员
        $scenarios['edit_admin'] = ['id', 'member_ids'];

        // 删除
        $scenarios['delete'] = ['id'];

        return $scenarios;
    }

    /**
     * @return array
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'project_name' => '项目名称',
            'sort' => '排序',
            'status' => '状态',
            'member_ids' => '人员',
        ];
    }
    /**
     * 检验项目ID
     * @param $attribute
     * @return void
     */
    public function checkId($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        $project = $this->getProject();
        if (!$project) {
            $this->addError($attribute, '项目不存在');
            return;
        }

        if ($project->status == Project::STATUS_DELETE) {
            $this->addError($attribute, '项目已删除');
            return;
        }
    }

    /**
     * 校验项目名称
     * @param $attribute
     * @return void
     */
    public function checkProjectName($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        $len = mb_strlen($this->project_name);
        if ($len > 20) {
            $this->addError($attribute, '项目名称过长，最多20个字');
            return;
        }

        // 是否检验
        $isCheck = true;
        if ($this->getScenario() == 'edit') {
            $job = $this->getProject();
            // 项目参数未改变【跳过】
            if ($job->project_name == $this->project_name) {
                $isCheck = false;
            }
        }

        if ($isCheck) {
            $one = Project::findOne([
                'project_name' => $this->project_name,
                'status' => [Project::STATUS_INVALID, Project::STATUS_ENABLE],
            ]);
            if ($one) {
                $this->addError($attribute, "项目【{$this->project_name}】已存在");
                return;
            }
        }
    }

    /**
     * 校验项目排序
     * @param $attribute
     * @return void
     */
    public function checkSort($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        if ($this->sort < 0) {
            $this->addError($attribute, '排序值不能小于0');
            return;
        }
    }

    /**
     * 校验项目状态
     * @param $attribute
     * @return void
     */
    public function checkStatus($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        if (!in_array($this->status, [Project::STATUS_INVALID, Project::STATUS_ENABLE])) {
            $this->addError($attribute, "非法状态");
            return;
        }
    }

    /**
     * 校验人员IDs
     * @param $attribute
     * @return void
     */
    public function checkMemberIds($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        $projectMemberList = $this->getProjectMemberList();
        $memberList = $this->getMemberList();
        if (array_diff(array_column($memberList, 'id'), array_column($projectMemberList, 'id'))) {
            $this->addError($attribute, "存在人员非当前项目");
            return;
        }
    }

    /**
     * 获取项目信息
     * @return Project|null
     */
    public function getProject(): ?Project
    {
        if (empty($this->_project)) {
            $this->_project = Project::findOne($this->id);
        }

        return $this->_project;
    }

    /**
     * 获取项目信息
     * @return array
     */
    public function getMemberIds(): array
    {
        if (is_null($this->_memberIdsFormat)) {
            $this->_memberIdsFormat = is_array($this->member_ids) ? $this->member_ids : [];
        }
        return $this->_memberIdsFormat;
    }

    /**
     * 获取项目信息
     * @return Member[]
     */
    public function getMemberList(): array
    {
        if (is_null($this->_memberList)) {
            $this->_memberList = MemberService::getNormalListByIds($this->getMemberIds());
        }
        return $this->_memberList;
    }

    /**
     * 获取项目人员列表
     * @return Member[]
     */
    public function getProjectMemberList(): array
    {
        if (is_null($this->_projectMemberList)) {
            $this->_projectMemberList = MemberService::getNormalListByIds(MemberProjectService::getMemberIdsByProjectId($this->id));
        }
        return $this->_projectMemberList;
    }
}
